﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Twc.Deployment.Client.Model;
using System.Collections.ObjectModel;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint;
using Twc.Deployment.Client.Logic;
using System.Threading;
using System.ComponentModel;
using System.Configuration;
using System.Windows.Threading;

namespace Twc.Deployment.Client.ViewModel
{
    public class DeploymentViewModel : INotifyPropertyChanged
    {
        private bool _deployWebConfig;
        private bool _deployWSP;
        private bool _restoreDB;
        private string _console;
        private bool _enabled;
        private string _title;
        private WebApplication _webApplication;
        

        private ObservableCollection<WebApplication> _webApps;

        public DeploymentViewModel()
        {
            _webApps = new ObservableCollection<WebApplication>();
            Title = String.Format("Welcome to {0} Deployment Wizard", ConfigurationSettings.AppSettings["Solution"]);
        }

        public string Title
        {
            get
            {
                return _title;
            }
            set
            {
                _title = value;
                NotifyPropertyChanged("Title");
            }
        }

        public ObservableCollection<WebApplication> WebApplications
        {
            get
            {
                return _webApps;
            }
        }

        public WebApplication WebApplication
        {
            get
            {
                return _webApplication;
            }
            set
            {
                _webApplication = value;
                NotifyPropertyChanged("WebApplication");
            }
        }

        public bool Enabled
        {
            get
            {
                return _enabled;
            }
            set
            {
                _enabled = value;
                NotifyPropertyChanged("Enabled");
            }
        }
        
        public SiteCollection SiteCollection
        {
            get;
            set;
        }
        
        public bool DeployWSP
        {
            get
            {
                return _deployWSP;
            }
            set
            {
                _deployWSP = value;
                NotifyPropertyChanged("DeployWSP");
            }
        }

        public bool RestoreDB
        {
            get
            {
                return _restoreDB;
            }
            set
            {
                _restoreDB = value;
                NotifyPropertyChanged("RestoreDB");
            }
        }

        public bool DeployWebConfig
        {
            get
            {
                return _deployWebConfig;
            }
            set
            {
                _deployWebConfig = value;
                NotifyPropertyChanged("DeployWebConfig");
            }
        }

        public void Deploy()
        {
            var deploymentService = new DeployService(SiteCollection);
            deploymentService.DeploySPBackup = RestoreDB;
            deploymentService.DeployWebConfig = DeployWebConfig;
            deploymentService.DeployWSP = DeployWSP;


            Console += "Starting deployment" + Environment.NewLine;
            Enabled = false;
            deploymentService.OnDeploymentAction += (input, output) => { Console += input + Environment.NewLine + output; };

            using (var worker = new BackgroundWorker())
            {
                worker.DoWork += (sender, e) => { deploymentService.Deploy(); };
                worker.RunWorkerCompleted += (sender, e) => { this.Enabled = true; };
                worker.RunWorkerAsync();
            }
        }



        public void LoadWebAppications()
        {
            try
            {
                Console = "Loading All Web Applications\n";
                var webApps = SPWebService.ContentService.WebApplications.Select(
                    webApplication =>
                        new WebApplication()
                        {
                            Guid = webApplication.Id,
                            Name = webApplication.Name,
                            Url = webApplication.AlternateUrls.FirstOrDefault().Uri.ToString(),
                            SiteCollections = getSiteCollections(webApplication)
                        });
                Console += "Web Applications Loaded\n";
                foreach (var webApp in webApps)
                {
                    foreach (var siteCollection in webApp.SiteCollections)
                    {
                        siteCollection.WebApplication = webApp;
                    }

                    _webApps.Add(webApp);
                }
            }
            catch (Exception ex)
            {
                Console = ex.ToString();
            }

        }

        private IList<SiteCollection> getSiteCollections(SPWebApplication webApplication)
        {
            var siteCollections = new List<SiteCollection>();

            foreach (SPSite spSiteCollection in webApplication.Sites)
            {
                siteCollections.Add(new SiteCollection()
                {
                    Guid = spSiteCollection.ID,
                    Name = spSiteCollection.PortalName,
                    Url = spSiteCollection.Url,
                });
                spSiteCollection.Dispose();
            }

            return siteCollections;
        }

        public string Console
        {
            get
            {
                return _console;
            }
            set
            {
                _console = value;
                NotifyPropertyChanged("Console");
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string info)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(info));
        }

        #endregion
    }
}
